/*
 * Copyright (c) 2009-2013 EvTech Project
 * All rights reserved.
 * 
 * This file is part of Symbol Matching.
 *
 * Symbol Matching is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version.
 *
 * Symbol Matching is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Symbol Matching.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package fi.honkalampisaatio.reaktiopeli.game;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;

import javax.swing.JPanel;

import fi.honkalampisaatio.game.game.LanguageResource;
import fi.honkalampisaatio.reaktiopeli.target.TargetEvent;
import fi.honkalampisaatio.reaktiopeli.target.TargetEventListener;
import fi.honkalampisaatio.reaktiopeli.xml.GameTime;
import fi.honkalampisaatio.reaktiopeli.xml.HighScore;
import fi.honkalampisaatio.reaktiopeli.xml.GameDifficulty.DIFFICULTY;

public class HighScorePanel extends JPanel  implements MouseListener {

	private static final long serialVersionUID = 7127508302800424927L;
	private String title;
	private String pressanybutton;
	private Hashtable<Player, HighScore> scores;
	private DIFFICULTY difficulty;
	private TargetEventListener listener = null;
	
	public HighScorePanel()
	{
		scores = null;
		this.addMouseListener(this);
		refreshLanguage();
	}

	public void setForeground(Color color)
	{
		super.setForeground(color);
		Component[] compList = this.getComponents();
		for(int i=0;i<compList.length;i++)
		{
			compList[i].setForeground(color);
		}
	}

	public void setFont(Font font)
	{
		super.setFont(font);
		Component[] compList = this.getComponents();
		for(int i=0;i<compList.length;i++)
		{
			compList[i].setFont(font);
		}
	}

	public void refreshLanguage()
	{
		LanguageResource dictionary = LanguageResource.getInstance();
		
		title = dictionary.get("HIGHSCORETITLE_TEXT");
		pressanybutton = dictionary.get("PRESS_ANY_BUTTON_TEXT");
	}

	/**
	 * Paints on screen
	 */
	public void paintComponent(Graphics g) {
        super.paintComponent(g);   
        Graphics2D g2 = (Graphics2D) g;
        LanguageResource dictionary = LanguageResource.getInstance();
		Rectangle2D rc = null;
		int x, y;
		int maxHeight, maxWidth;
		float fontSize = 144;
		int maxScoreCount = 5;
		String currentTitle = title;
		String difficultyStr = dictionary.get(this.difficulty.toString());
		if(difficultyStr!=null && !difficultyStr.isEmpty())
		{
			currentTitle += ": " + difficultyStr;
		}
    	
    	// title
		maxHeight = (int) (this.getHeight()*0.1f);
		maxWidth = (int) (this.getWidth()*0.6f);
    	g2.setFont(getFont().deriveFont((float) (fontSize)));
    	if(g2.getFontMetrics().getHeight()!=0) {
    		fontSize = (int)(fontSize * maxHeight/g2.getFontMetrics().getHeight());
        	g2.setFont(getFont().deriveFont(fontSize));
    	}
    	rc = g2.getFontMetrics().getStringBounds(currentTitle, g2);
    	if(rc.getWidth()!=0 && rc.getWidth()>maxWidth) {
    		fontSize = (float) (fontSize * maxWidth/rc.getWidth());
        	g2.setFont(getFont().deriveFont(fontSize));
        	rc = g2.getFontMetrics().getStringBounds(currentTitle, g2);
    	}
    	y = (int) (g2.getFontMetrics().getMaxAscent() + this.getHeight()*0.04f);
    	x = (int)((this.getWidth()-rc.getWidth())/2);
    	g2.drawString(currentTitle, x, y);
    	
    	if(scores!=null && scores.size()!=0)
    	{
    		ArrayList<ArrayList<String>> columnsString = new ArrayList<ArrayList<String>>();
    		int vgap = (int)(this.getWidth()*0.1f);
    		int hgap = (int)(this.getHeight()*0.02f);
    		int columnWidth = (int)((this.getWidth()-vgap)/scores.size())-vgap;
    		int columnHeight = (int)((this.getHeight()*0.58f)/maxScoreCount)-hgap;
    		//define font size
        	if(g2.getFontMetrics().getHeight()!=0) {
        		fontSize = (int)(fontSize * columnHeight/g2.getFontMetrics().getHeight());
            	g2.setFont(getFont().deriveFont(fontSize));
        	}
    		Iterator<Player> playerIterator = scores.keySet().iterator();
    		while(playerIterator.hasNext())
    		{
        		ArrayList<String> rowString = new ArrayList<String>();
    			Player player = playerIterator.next();
    			HighScore  playerScores = scores.get(player);
        		//define font size
            	rc = g2.getFontMetrics().getStringBounds(player.getPlayerName(), g2);
            	if(rc.getWidth()!=0 && rc.getWidth()>columnWidth) {
            		fontSize = (float) (fontSize * columnWidth/rc.getWidth());
                	g2.setFont(getFont().deriveFont(fontSize));
                	rc = g2.getFontMetrics().getStringBounds(player.getPlayerName(), g2);
            	}
            	rowString.add(player.getPlayerName());
    			for(int i=0; playerScores.getScores(difficulty)!=null && 
    					i<maxScoreCount && i<playerScores.getScores(difficulty).size() ;i++)
    			{
    				GameTime time = playerScores.getScores(difficulty).get(i);
    				String score = (i+1) + ". " + dictionary.get("SCORES") + ":" + 
    						time.getScore() + 
    						" (" + dictionary.get("TIME") + ": " + 
    						time.getTime(dictionary.get("TIMEFORMAT")) + ")";
    				if(playerScores.getLastRowAdded()==i)
    				{
    					score = score + " "+ dictionary.get("HIGHSCORE_NEW_TEXT");
    				}
            		//define font size
                	rc = g2.getFontMetrics().getStringBounds(score, g2);
                	if(rc.getWidth()!=0 && rc.getWidth()>columnWidth) {
                		fontSize = (float) (fontSize * columnWidth/rc.getWidth());
                    	g2.setFont(getFont().deriveFont(fontSize));
                    	rc = g2.getFontMetrics().getStringBounds(score, g2);
                	}
                	rowString.add(score);
    			}
    			columnsString.add(rowString);
    		}

    		x = vgap;
    		Iterator<ArrayList<String>> cIterator = columnsString.iterator();
    		while(cIterator.hasNext())
    		{
        		y = (int) (this.getHeight()*0.25f);
    			g2.drawRect(x, y/*-columnHeight*/, columnWidth, (columnHeight+hgap)*(maxScoreCount));
        		Iterator<String> rIterator = cIterator.next().iterator();
        		while(rIterator.hasNext())
        		{
        			String scoreStr = rIterator.next();
                	g2.drawString(scoreStr, x, y);
            		y = y+hgap+columnHeight;
        		}
    			x = x + vgap + columnWidth;
    		}
    	}

    	// press any button text
		maxHeight = (int) (this.getHeight()*0.1f);
		maxWidth = (int) (this.getWidth()*0.6f);
    	g2.setFont(getFont().deriveFont((float) (fontSize)));
    	if(g2.getFontMetrics().getHeight()!=0) {
    		fontSize = (int)(fontSize * maxHeight/g2.getFontMetrics().getHeight());
        	g2.setFont(getFont().deriveFont(fontSize));
    	}
    	rc = g2.getFontMetrics().getStringBounds(pressanybutton, g2);
    	if(rc.getWidth()!=0 && rc.getWidth()>maxWidth) {
    		fontSize = (float) (fontSize * maxWidth/rc.getWidth());
        	g2.setFont(getFont().deriveFont(fontSize));
        	rc = g2.getFontMetrics().getStringBounds(pressanybutton, g2);
    	}
    	y = (int) (g2.getFontMetrics().getMaxAscent() + this.getHeight()*0.86f);
    	x = (int)((this.getWidth()-rc.getWidth())/2);
    	g2.drawString(pressanybutton, x, y);
	}


	public void setScores(DIFFICULTY difficulty, Hashtable<Player, HighScore> scores) {
		this.scores = scores;
		this.difficulty = difficulty;
	}
	
	 public void mouseClicked (MouseEvent e) { } 
	 public void mouseEntered (MouseEvent e) { } 
	 public void mouseExited  (MouseEvent e) { }
	 public void mouseReleased(MouseEvent e) { }
	 
	 /* Handle the users mouse press and pass it to fire event same as if the user pressed keyboard */
	 public void mousePressed (MouseEvent e) {	
		 System.out.println("mousePressed");
			TargetEvent tEvent = new TargetEvent(this, -1, TargetEvent.TYPE.PRESS);
			fireTargetEvent(tEvent);	 
			 
	 } 
		public void addTargetEventListener(TargetEventListener listener) {
			this.listener = listener;
		}
		
		public void removeTargetEventListener(TargetEventListener listener) {
			if(this.listener==listener) {
				listener=null;
			}
		}
		
		private void fireTargetEvent(TargetEvent e) {
			if(listener!=null) {
				listener.targetEventOccurred(e);
			}
		}
}
